using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using NUnit.Framework;
using XcoAppSpaces.Core.Ports;
using XcoAppSpaces.Core.Ports.Remoting;

namespace test.XcoAppSpaces.Core.Ports
{
	[TestFixture]
	public class RemotePortTests
	{
		[Test]
		public void PostRemoted_transports_context_and_causalities()
		{
			//Arrange
			var causalities = new List<ICausality>{new Causality(new Port<Exception>())};
			var msgContext = new MessageContext {RemoteAddress = "test123"};
			List<ICausality> actualCausalities = null;
			MessageContext actualMessageContext = null;
			IRemotedPost port = new Port<int>(_ =>
			{
				actualCausalities = CausalityContext.ActiveCausalities.ToList();
				actualMessageContext = MessageContext.Current;
			});

			//Act
			port.PostRemoted(123, causalities, msgContext);

			//Assert
			SpinWait.SpinUntil(() => actualMessageContext != null, 1000);
			Assert.That(actualCausalities, Is.EqualTo(causalities));
			Assert.That(actualMessageContext, Is.EqualTo(msgContext));
		}

		[Test]
		public void PostRemoted_works_for_portsets()
		{
			//Arrange
			var causalities = new List<ICausality> { new Causality(new Port<Exception>()) };
			var msgContext = new MessageContext { RemoteAddress = "test123" };
			List<ICausality> actualCausalities = null;
			MessageContext actualMessageContext = null;
			var portset = new PortSet<int, string>();
			portset.P0.RegisterReceiver(_ =>
			{
				actualCausalities = CausalityContext.ActiveCausalities.ToList();
				actualMessageContext = MessageContext.Current;
			});

			//Act
			((IRemotedPost)portset).PostRemoted(123, causalities, msgContext);

			//Assert
			SpinWait.SpinUntil(() => actualMessageContext != null, 1000);
			Assert.That(actualCausalities, Is.EqualTo(causalities));
			Assert.That(actualMessageContext, Is.EqualTo(msgContext));
		}
	}
}